Conversation
6704277 to
433c29e
Compare
|
I think this give us exactly what we need. My only concern is that it sacrifices compile-type parameter checking, which is a substantial part of the value of gophercloud. I wonder if we could write something with strongly-typed arguments. If we were keen enough I'm pretty sure it could also be generated from base ListOpts argument. |
|
It would be nice to be able to easily merge an existing ListOpts object with this |
or maybe that's a bad idea. Being able to merge a ListOpts with this would give the impression that you can have "this set of properties" OR "this property", while it will just merge the common properties instead. |
|
I would be inclined to add a new struct explicitly for each resource which can use it, alongside the existing ListOpts. Maybe (ports|subnets|networks).ListOptsMulti? Little bit more boilerplate, but at least we wouldn't be accidentally adding support where we shouldn't. |
433c29e to
ef70c17
Compare
With `query.ListOpts`, it should be easier to list resources based on repeated properties. For example: get information about multiple ports by ID with a single call. ListOpts is currently implemented for three Network resources: * ports * networks * subnets
ef70c17 to
1fe62ca
Compare
Can you give me an example of what you mean? |
|
I have added a bit of reflection. This gives a minimal (runtime) type check that may or may not add some safety. |
|
and @spjmurray if you happen to pass by! |
|
Yup, this looks pretty good to me. |
Firstly I don't think we are adding support where we shouldn't because we need to implement the relevant interfaces for each point of use, specifically It feels a bit smelly to have this here. If we can successfully make it generic I would probably put it somewhere like However, this is really an actual part of the API. I feel like it should live in https://github.com/gophercloud/gophercloud/blob/master/openstack/networking/v2/networks/requests.go alongside |
|
Ah yes, this is what we need! Just for discussion purposes we could actually get this working today with something like: import (
"fmt"
"net/url"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
)
type MyListOpts struct {
ports.ListOpts
Name []string `q:"name"`
}
func BuildCompositeQueryString(opts, base interface{}) (url.Values, error) {
baseURL, err := gophercloud.BuildQueryString(base)
if err != nil {
return nil, err
}
optsURL, err := gophercloud.BuildQueryString(opts)
if err != nil {
return nil, err
}
baseQuery := baseURL.Query()
for parameter, values := range optsURL.Query() {
baseQuery.Del(parameter)
for _, value := range values {
baseQuery.Add(parameter, value)
}
}
return baseQuery, nil
}
func (opts MyListOpts) ToPortListQuery() (string, error) {
values, err := BuildCompositeQueryString(opts, opts.ListOpts)
return values.Encode(), err
}
func main() {
opts := MyListOpts{
ListOpts: ports.ListOpts{
Status: "detached",
Name: "ignored, hopefully",
},
Name: []string{
"port1",
"port2",
},
}
query, err := opts.ToPortListQuery()
if err != nil {
fmt.Println("fail", err)
}
fmt.Println(query)
}Kinda ugly though! The obvious other way would be to have: type MultiOpts struct {
Name []string `q:"name"`
}
type ListOpts struct {
Name string `q:"name"`
MultiOpts MultiOpts
} |
Here I propose a builder for List queries that allows "OR" clauses.
With
query.New, it should be easier to list resources based on repeated properties. For example: get information about multiple ports by ID with a single call.The properties that can be passed with the method
.And(property string, values ...interface{})are guarded by the fields taggedq:in the base filter. For example: when callingAnd()onquery.New(nertworks.ListOpts{}), theAndproperty name must be one of those defined in thenetwork.ListOptsfilter.For example:
ListOpts is currently implemented for three Network resources: